using AutoMapper;
using B.S.NewMedical.Api.Read.Application.Command.ContentManagement.Department;
using B.S.NewMedical.Api.Read.DTOS.Department;
using B.S.NewMedical.Domain.Doctor;
using B.S.NewMedical.ErrorCode;
using B.S.NewMedical.Infrastructure.Interface;
using MediatR;
using Microsoft.Extensions.Logging;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace B.S.NewMedical.Api.Read.Application.Handler.ContentManagement.Department
{
    /// <summary>
    /// 获取二级科室列表处理器
    /// </summary>
    public class GetSecondLevelDepartmentsHandler : IRequestHandler<GetSecondLevelDepartmentsCommand, ApiPageing<DepartmentDisplayDto>>
    {
        private readonly IBaseRepository<DepartmentModel> _departmentRepository;
        private readonly ILogger<GetSecondLevelDepartmentsHandler> _logger;
        private readonly IMapper _mapper;

        public GetSecondLevelDepartmentsHandler(
            IBaseRepository<DepartmentModel> departmentRepository,
            ILogger<GetSecondLevelDepartmentsHandler> logger,
            IMapper mapper)
        {
            _departmentRepository = departmentRepository ?? throw new ArgumentNullException(nameof(departmentRepository));
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));
            _mapper = mapper ?? throw new ArgumentNullException(nameof(mapper));
        }

        /// <summary>
        /// 处理获取二级科室列表请求
        /// </summary>
        public async Task<ApiPageing<DepartmentDisplayDto>> Handle(GetSecondLevelDepartmentsCommand request, CancellationToken cancellationToken)
        {
            try
            {
                _logger.LogInformation("开始查询二级科室列表，父级科室ID：{ParentId}，查询条件：{@QueryDto}", 
                    request.ParentDepartmentId, request.QueryDto);

                // 构建查询条件
                var query = _departmentRepository.GetAll();
                
                // 过滤二级科室（ParetId = 指定的父级科室ID）
                query = query.Where(d => d.ParetId == request.ParentDepartmentId && !d.IsDeleted);

                // 科室名称模糊查询
                if (!string.IsNullOrWhiteSpace(request.QueryDto.DepartmentName))
                {
                    query = query.Where(d => d.DepartmentName.Contains(request.QueryDto.DepartmentName));
                }

                // 科室类型筛选
                if (!string.IsNullOrWhiteSpace(request.QueryDto.Type))
                {
                    query = query.Where(d => d.Type == request.QueryDto.Type);
                }

                // 状态筛选
                if (request.QueryDto.IsOnline.HasValue)
                {
                    query = query.Where(d => d.IsOnline == request.QueryDto.IsOnline.Value);
                }

                // 排序
                query = query.OrderByDescending(d => d.CreateTime);

                // 先获取父级科室信息，避免后续并发查询
                string? parentDepartmentName = null;
                try
                {
                    var parentDepartment = await _departmentRepository.GetValue(request.ParentDepartmentId);
                    parentDepartmentName = parentDepartment?.DepartmentName;
                }
                catch (Exception ex)
                {
                    _logger.LogWarning(ex, "查询父级科室信息失败，父级科室ID：{ParentId}", request.ParentDepartmentId);
                }

                // 分页 - 使用异步方法避免连接冲突
                var totalCount = await query.CountAsync(cancellationToken);
                var totalPage = (int)Math.Ceiling((double)totalCount / request.QueryDto.PageSize);
                var departments = await query
                    .Skip((request.QueryDto.PageIndex - 1) * request.QueryDto.PageSize)
                    .Take(request.QueryDto.PageSize)
                    .ToListAsync(cancellationToken);

                // 映射为DTO
                var departmentDtos = departments.Select(dept => {
                    var dto = _mapper.Map<DepartmentDisplayDto>(dept);
                    dto.Level = "二级科室";
                    dto.ParentDepartmentName = parentDepartmentName;
                    return dto;
                }).ToList();

                _logger.LogInformation("查询二级科室列表成功，返回 {Count} 条记录", departmentDtos.Count);

                return new ApiPageing<DepartmentDisplayDto>
                {
                    Code = ApiEnum.Success,
                    Msg = "查询成功",
                    PageData = departmentDtos,
                    TotaCount = totalCount,
                    TotaPage = totalPage
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "查询二级科室列表时发生错误，父级科室ID：{ParentId}", request.ParentDepartmentId);
                return new ApiPageing<DepartmentDisplayDto>
                {
                    Code = ApiEnum.Error,
                    Msg = "查询失败",
                    PageData = new List<DepartmentDisplayDto>()
                };
            }
        }
    }
}